﻿#include "ProjectFileIO.h"
#include <QDomDocument>
#include <QTextStream>
#include <QDataStream>
#include <QDomNodeList>
#include <QDomElement>
#include <QDomText>
#include <QDomAttr>
#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include <JlCompress.h>
#include "BaseModule/GlobalHelper.h"
#include "DataManager/ProjectTreeData.h"
#include "DataManager/WindowTotalData.h"
//#include "PluginManager/PluginManager.h"
#include "BaseWidget/IWidgetSignal.h"

namespace ProjectManager
{
    ProjectFileIO::ProjectFileIO(const QString& fileName, ProjectOperateType operateType)
        :IOBase(fileName)
        , BaseWidget::ThreadTask()
        , m_operateType(operateType)
    {
        //totalData
        m_windowTotalData = DataManager::WindowTotalData::getInstance();
        m_tempIODir = GlobalHelperInstance->getProjectTempIODir() +"/";
    }

    void ProjectFileIO::run()
    {
        bool _isSuccess = false;   
        if (m_operateType == ProjectOperateType::Open)
        {
            GlobalHelperInstance->setIsOpenProject(true);
            GlobalHelperInstance->createTempDir();
            if (GlobalHelperInstance->createProjectTempDir(m_fileName))
            {
                // emit IBaseSignalInstance->signal_updateCaseDir();
                // emit IBaseSignalInstance->signal_updateProjectTempDir();
                _isSuccess = this->read();
                GlobalHelperInstance->deleteProjectTempDir();
            }
            else
            {
                _isSuccess = false;
            }
            GlobalHelperInstance->setIsOpenProject(false);
        }
        else if (m_operateType == ProjectOperateType::Save)
        {
            if (GlobalHelperInstance->createProjectTempDir(m_fileName))
            {
                //emit IBaseSignalInstance->signal_updateCaseDir();
                //emit IBaseSignalInstance->signal_updateProjectTempDir();
                _isSuccess = this->write();
                GlobalHelperInstance->deleteProjectTempDir();
            }
            else
            {
                _isSuccess = false;
            }
        }
        else if (m_operateType == ProjectOperateType::Create)
        {
            if (GlobalHelperInstance->createProjectTempDir(m_fileName))
            {
                //emit IBaseSignalInstance->signal_updateCaseDir();
                //emit IBaseSignalInstance->signal_updateProjectTempDir();
                _isSuccess = this->create();               
            }
            else
            {
                _isSuccess = false;
            }
        }
        ThreadTask::threadTaskFinished();
        m_execFinish = true;
    }

    bool ProjectFileIO::write(QString fileName)
    {
        if (fileName.isEmpty())
        {
            fileName = m_fileName;
        }

        bool _isOK = false;
        QString _suffix = fileName.right(4).toLower();
        qDebug() << fileName << _suffix;
        if (_suffix == ".xml")
        {
            //_isOK = writeXml(fileName);
            _isOK = false;
        }
        else if (_suffix == ".ppc")
        {
            _isOK = writePPC(fileName);
        }

        if (_isOK && m_savePy)
        {
            QStringList _pyCodes{};
            QString _fileName = "\"" + fileName + "\"";
            _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
            _pyCodes += QString("appPrj.doPrjFileWrite(%1)").arg(_fileName);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }

        return _isOK;
    }

    bool ProjectFileIO::writePPC(QString fileName, bool isSave)
    {
        bool _isOK = false;
        
        //写json
        ProjectTreeDataInstance->writeConfig();

        //评估提交目录复制
        QString _sourcedir = GlobalHelperInstance->getAppInstallDir() + "/SubmitEvaluation";
        QString _targetdir = GlobalHelperInstance->getProjectTempIODir() + "/SubmitEvaluation";
        GlobalHelperInstance->copyFolder(_sourcedir, _targetdir, true);
        m_doc = new QDomDocument();
        QDomProcessingInstruction _instruction = m_doc->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
        m_doc->appendChild(_instruction);
        QDomElement _root = m_doc->createElement("PPC_FILE_1.0");
        m_doc->appendChild(_root);
    
        if (isSave)
        {
            //写xml
            m_windowTotalData->writeToProjectFile(m_doc, &_root);
        }

        QFile _file(GlobalHelperInstance->getProjectTempFilePath() + "/PostProcessing.xml");
        if (!_file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
        {
            return false;
        }
        m_stream = new QTextStream(&_file);
        m_doc->save(*m_stream, 4);
        _file.close();
        _isOK = JlCompress::compressDir(fileName, GlobalHelperInstance->getProjectTempIODir());
        return _isOK;
    }

    bool ProjectFileIO::writeXml(QString fileName, bool isSave)
    {
        bool _isEmpty = true;
        m_doc = new QDomDocument;
        QDomProcessingInstruction _instruction = m_doc->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
        m_doc->appendChild(_instruction);
        QDomElement _root = m_doc->createElement("PPC_FILE_1.0");
        m_doc->appendChild(_root);

        if (isSave)
        {
            //const int _modelCount = m_modelData->getModelCount();
            //if (_modelCount > 0) //写出物理模型
            //{
            //    _isEmpty = false;
            //    m_modelData->writeToProjectFile(m_doc, &_root);
            //}
        }

//        if (isEmpty) return false;  //数据为空 不写文件
        if (!m_file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
        {
            return false;
        }
        m_stream = new QTextStream(&m_file);
        m_doc->save(*m_stream, 4);
        m_file.close();

        return true;
    }

    bool ProjectFileIO::read()
    {
        bool _isOK = false;
        QString _fileName = m_fileName;
        //qDebug() << _fileName;
        QString suffix = _fileName.right(4);
        if (suffix == ".xml")
        {
            //_isOK = readXml(_fileName);
            _isOK = false;
        }
        else if (suffix == ".ppc")
        {
            _isOK = readPPC(_fileName);
        }

        if (_isOK && m_savePy)
        {
            QStringList _pyCodes{};
            QString _fileName = "\"" + m_fileName + "\"";
            _pyCodes += QString("appPrj = PostProcessing.AppPrj()");
            _pyCodes += QString("appPrj.doPrjFileRead(%1)").arg(_fileName);
            emit IBaseSignalInstance->signal_execPYCode(_pyCodes, true, false);
        }

        return _isOK;
    }

    bool ProjectFileIO::readXml(QString fileName)
    {
        if (!m_file.open(QIODevice::ReadOnly | QFile::Text))
        {
            return false;
        }
        m_doc = new QDomDocument();
        int _row{0}, _col{0};
        QString _errstr{};
        if (!m_doc->setContent(&m_file, true, &_errstr, &_row, &_col))
        {
            qDebug() << _errstr << "line: " << _row << "col: " << _col;
            m_file.close();
            return false;
        }
        QDomNodeList _modelNodeList = m_doc->elementsByTagName("ModelData");
        readModelData(&_modelNodeList);
        m_file.close();

        return true;
    }

    bool ProjectFileIO::readPPC(QString fileName)
    {
        IBaseSignalInstance->signal_clearCurrentProjectAllData();

        if (GlobalHelperInstance->createProjectTempDir(fileName))
            return false;
        //emit IBaseSignalInstance->signal_updateCaseDir();
        //emit IBaseSignalInstance->signal_updateProjectTempDir();
        QStringList _files = JlCompress::extractDir(fileName, GlobalHelperInstance->getProjectTempIODir());
        if (!(_files.size()))
        {
            return false;
        }

        QFile _file(GlobalHelperInstance->getProjectTempFilePath() + "/PostProcessing.xml");
        if (!_file.open(QIODevice::ReadOnly | QFile::Text))
        {
            return false;
        }

        QString _errorMsg;
        int _errorLine{ 0 };
        int _errorColumn{ 0 };
        m_doc = new QDomDocument();
        if (!m_doc->setContent(&_file, &_errorMsg, &_errorLine, &_errorColumn))
        {
            _file.close();
            QString _msg = QObject::tr("Message:%1, row:%2, col:%3").arg(_errorMsg).arg(_errorLine).arg(_errorColumn);
            QString msg = tr("Project File Error Info: %1").arg(_msg);
            //更新状态信息和弹窗
            //emit this->signal_showText(msg);
            //emit IWidgetSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, msg);
            qDebug() << _msg;
            return false;
        }

        //读json
        ProjectTreeDataInstance->readConfig();
        //评估提交目录复制
        QString _sourcedir = GlobalHelperInstance->getProjectTempIODir() + "/SubmitEvaluation" ;
        QString _targetdir = GlobalHelperInstance->getAppInstallDir() + "/SubmitEvaluation";
        GlobalHelperInstance->copyFolder(_sourcedir, _targetdir, true);
        //读xml
        QDomNodeList modelNodeList = m_doc->elementsByTagName("GraphWindowData");
        readModelData(&modelNodeList);

        _file.close();

        return true;
    }

    bool ProjectFileIO::create(QString fileName)
    {
        if (fileName.isEmpty())
        {
            fileName = m_fileName;
        }

        bool _isOK = false;
        QString _suffix = fileName.right(4).toLower();
        qDebug() << fileName << _suffix;
        if (_suffix == ".xml")
        {
            _isOK = false;
        }
        else if (_suffix == ".ppc")
        {
            _isOK = writePPC(fileName, false);
        }

        return _isOK;
    }  
    bool ProjectFileIO::readModelData(QDomNodeList* nodeList)
    {
        const int _nodeCount = nodeList->size();
        if (_nodeCount != 1)
        {
            return false;
        }
        return m_windowTotalData->readDataFromProjectFile(nodeList);
    }
}
